/* ====================================================================
 * (#)Header: CrudAction.java
 * (#)Revision: 
 * (#)Date Created: 2009-02-20
 * (#)Created By: Karol Wozniak
 * ====================================================================
 *
 * Copyright (c) 2007 karolak .  All rights reserved.
 *
 * ====================================================================
 * 
 * The software application represented here is the sole property of 
 * karolak. Its unauthorized utilization is expressly prohibited.
 * 
 * ====================================================================
 */
package com.karolak.web.saf.action;

import com.karolak.service.Service;
import com.karolak.web.saf.command.ActionCommand;

/**
 * <code>CrudAction</code> implements CRUD functions.
 * 
 * @author <a href="mailto:kwozniak@hotmail.com">Karol Wozniak</a>
 */
public abstract class CrudAction<T, Id, S extends Service<T, Id>> extends ModelAction<T, Id, S> {

	private static final long serialVersionUID = 1L;

	// === work flow commands === //
	private ActionCommand addCommand;
	private ActionCommand saveCommand;
	private ActionCommand editCommand;
	private ActionCommand updateCommand;
	private ActionCommand removeCommand;
	private ActionCommand listCommand;

	// === action workflows === //
	/**
	 * Prepare
	 */
	public void prepare() {
	}

	/**
	 * Default action
	 */
	@Override
	public String execute() {
		return list();
	}

	/**
	 * List entities
	 * 
	 * @return
	 */
	public String list() {
		return getListCommand().execute(this);
	}

	// === Create entity workflow === //
	public void prepareAdd() {
		getAddCommand().prepare(this);
	}

	/**
	 * Display input form.
	 */
	public String add() {
		return getAddCommand().execute(this);
	}

	public void prepareSave() {
		getSaveCommand().prepare(this);
	}

	/**
	 * Perform custom validation in addition to framework validation.
	 */
	public void validateSave() {
		getSaveCommand().validate(this);
	}

	/**
	 * Create entity in database.
	 * 
	 * @return
	 * @throws Exception
	 */
	public String save() {
		return getSaveCommand().execute(this);
	}

	// === Edit entity workflow === //

	/**
	 * Edit is excluded from validation, so some validation is performed here.
	 */
	public void prepareEdit() {
		getEditCommand().prepare(this);
	}

	/**
	 * Display edit form.
	 */
	public String edit() {
		return getEditCommand().execute(this);
	}

	/**
	 * Retrieve entity on which form parameters will be set.
	 */
	public void prepareUpdate() {
		getUpdateCommand().prepare(this);
	}

	/**
	 * Perform custom validation in addition to framework validation.
	 */
	public void validateUpdate() {
		getUpdateCommand().validate(this);
	}

	/**
	 * Update entity in database.
	 * 
	 * @return
	 * @throws Exception
	 */
	public String update() {
		return getUpdateCommand().execute(this);
	}

	// === delete workflow === //
	/**
	 * Display entity form.
	 */
	// TODO workflow ? like edit
	public String destroy() {
		return INPUT;
	}

	public void prepareRemove() {
		getRemoveCommand().prepare(this);
	}

	/**
	 * Perform custom validation in addition to framework validation.
	 */
	public void validateRemove() {
		getRemoveCommand().validate(this);
	}

	/**
	 * Delete entity from database.
	 * 
	 * @return
	 * @throws Exception
	 */
	public String remove() {
		return getRemoveCommand().execute(this);
	}

	// === get/set ===//
	public ActionCommand getSaveCommand() {
		return saveCommand;
	}

	public void setSaveCommand(ActionCommand saveCommand) {
		this.saveCommand = saveCommand;
	}

	public ActionCommand getAddCommand() {
		return addCommand;
	}

	public void setAddCommand(ActionCommand addCommand) {
		this.addCommand = addCommand;
	}

	public ActionCommand getEditCommand() {
		return editCommand;
	}

	public void setEditCommand(ActionCommand editCommand) {
		this.editCommand = editCommand;
	}

	public ActionCommand getUpdateCommand() {
		return updateCommand;
	}

	public void setUpdateCommand(ActionCommand updateCommand) {
		this.updateCommand = updateCommand;
	}

	public ActionCommand getRemoveCommand() {
		return removeCommand;
	}

	public void setRemoveCommand(ActionCommand removeCommand) {
		this.removeCommand = removeCommand;
	}

	public ActionCommand getListCommand() {
		return listCommand;
	}

	public void setListCommand(ActionCommand listCommand) {
		this.listCommand = listCommand;
	}
}
